#pragma once

#include "TimeConstraint.h"

#include "TimeInterval.h"

namespace uml {

const bool TimeConstraint::firstEvent_default_ = true;
TimeConstraint::TimeConstraint(const QString& umlType)
    : IntervalConstraint(umlType) {}

void TimeConstraint::fromJson(const QJsonObject& json, QStringList& errorList) {
    if (json.isEmpty()) {
        return;
    }

    IntervalConstraint::fromJson(json, errorList);
    firstEvent_ = json.value("firstEvent").toBool(firstEvent_default_);
    specification_ = JsonSerializable::create<TimeInterval>(json.value("specification"), errorList);

}

void TimeConstraint::toJson(QJsonObject& json) {
    IntervalConstraint::toJson(json);
    if (firstEvent_ != firstEvent_default_) {
        json.insert("firstEvent", firstEvent_);
    }
    if (specification_) {
        QJsonObject specification_json;
        specification_->toJson(specification_json);
        json.insert("specification", specification_json);
    }
}

/// <summary>
/// firstEvent getter
/// The value of firstEvent is related to the constrainedElement. If firstEvent is
/// true, then the corresponding observation event is the first time instant the
/// execution enters the constrainedElement. If firstEvent is false, then the
/// corresponding observation event is the last time instant the execution is within
/// the constrainedElement.
/// </summary>
bool TimeConstraint::firstEvent() const {
    return firstEvent_;
}

/// <summary>
/// firstEvent setter
/// The value of firstEvent is related to the constrainedElement. If firstEvent is
/// true, then the corresponding observation event is the first time instant the
/// execution enters the constrainedElement. If firstEvent is false, then the
/// corresponding observation event is the last time instant the execution is within
/// the constrainedElement.
/// </summary>
void TimeConstraint::setFirstEvent(bool value) {
    firstEvent_ = value;
}

/// <summary>
/// specification getter
/// TheTimeInterval constraining the duration.
/// </summary>
shared_ptr<TimeInterval> TimeConstraint::specification() const {
    return specification_;
}

/// <summary>
/// specification setter
/// TheTimeInterval constraining the duration.
/// </summary>
void TimeConstraint::setSpecification(shared_ptr<TimeInterval> value) {
    specification_ = value;
}

} // namespace uml
